package com.loan.web.utils;

import com.loan.common.pdf.PDFUtil;
import com.loan.common.utils.StringUtils;
import com.loan.system.create.domain.*;
import com.loan.system.create.service.IAssistPdfSearchJhBaseService;
import com.loan.system.create.service.IAssistPdfSearchNhBaseService;
import com.loan.system.create.service.IAssistPdfSearchWxBaseService;
import com.loan.system.create.service.IAssistPdfSearchZfbBaseService;
import com.loan.system.domain.work.domain.JhPdfDomain;
import com.loan.system.domain.work.domain.NhPdfDomain;
import com.loan.system.domain.work.domain.WxPdfDomain;
import com.loan.web.pdf.CommonDomain;
import com.loan.web.pdf.NhDomain;
import com.loan.web.pdf.WxDomain;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 解析并入库明细数据工具类
 */
@Slf4j
@Component
public class ExtractorBankUtil {

    @Autowired
    private IAssistPdfSearchJhBaseService assistPdfSearchJhBaseService;
    @Autowired
    private IAssistPdfSearchNhBaseService assistPdfSearchNhBaseService;
    @Autowired
    private IAssistPdfSearchWxBaseService assistPdfSearchWxBaseService;
    @Autowired
    private IAssistPdfSearchZfbBaseService assistPdfSearchZfbBaseService;

    /**
     * JH数据检索入库
     *
     * @param filePath 文件所在路径
     */
    public void extractorJhBankData(String filePath) {
        try {
            PdfDocument pdf = new PdfDocument();
            pdf.loadFromFile(filePath);
            // pdf的总页数
            int pageTotalNum = pdf.getPages().getCount();
            // 由于spire.office只可以读取前10页pdf的内容，则进行拆分pdf
            // 份数
            int copies = pageTotalNum / 10;
            // 取余
            int remainder = pageTotalNum % 10;
            if (remainder > 0) {
                // 余数大于0, 份数+1
                copies++;
            }
            // 放置以获取到的信息
            List<CommonDomain> list = new ArrayList<>();
            // 按份数抽取表格
            for (int cps = 0; cps < copies; cps++) {
                PdfDocument doc = new PdfDocument();
                // 拆分读取的起始页
                int start = cps * 10;
                // 结尾页
                int end = (start + 9) > (pageTotalNum - 1) ? (pageTotalNum - 1) : (start + 9);
                // 将读取到的数据初始化到新的PdfDocument中
                doc.insertPageRange(pdf, start, end);
                // 通过工具抽取表格
                PdfTableExtractor extractor = new PdfTableExtractor(doc);
                PdfTable[] tableLists;
                for (int page = 0; page < doc.getPages().getCount(); page++) {
                    tableLists = extractor.extractTable(page);
                    if (tableLists != null) {
                        for (PdfTable table : tableLists) {
                            List<String[]> detailList = new ArrayList<>();
                            int row = table.getRowCount();
                            int column = table.getColumnCount();
                            for (int i = 1; i < row; i++) {
                                for (int j = 0; j < column; j++) {
                                    String text = table.getText(i, j);
                                    if (StringUtils.contains(text, "\n")) {
                                        String[] detailArray = text.split("\n");
                                        detailList.add(detailArray);
                                    }
                                }
                            }
                            if (!detailList.isEmpty()) {
                                int rowNum = detailList.get(0).length;
                                int size = detailList.size();
                                for (int i = 0; i < rowNum; i++) {
                                    Class<CommonDomain> aClass = CommonDomain.class;
                                    CommonDomain commonDomain = aClass.newInstance();
                                    // 获取当前列表中序列的总数
                                    for (int h = 0; h < size; h++) {
                                        int f = h + 1;
                                        Method method = aClass.getDeclaredMethod("setNote" + f, String.class);
                                        method.setAccessible(true);
                                        try {
                                            String[] details = detailList.get(h);
                                            String value = details[i]; // 值
                                            log.info("正常给值...");
                                            method.invoke(commonDomain, value);
                                        } catch (ArrayIndexOutOfBoundsException e) {
                                            log.info("数组越界，默认给空子串");
                                            method.invoke(commonDomain, "");
                                        }
                                    }
                                    list.add(commonDomain);
                                }
                            }
                        }
                    }
                }
                doc.clone();
            }
            pdf.clone();

            // 处理提取好的数据并入库
            if (!list.isEmpty()) {
                List<AssistPdfSearchJhBase> jhSearchList = new ArrayList<>();
                list.forEach(item -> {
                    AssistPdfSearchJhBase jhBase = new AssistPdfSearchJhBase();
                    jhBase.setJhBaseTransactionSummary(item.getNote2());
                    jhBase.setJhBaseTransactionCurrency(item.getNote3());
                    jhBase.setJhBaseTransactionBanknote(item.getNote4());
                    jhBase.setJhBaseTransactionAmount(new BigDecimal(item.getNote6().replace("-", "").replace(",", "")));
                    jhBase.setJhBaseTransactionType(StringUtils.startsWith(item.getNote6(), "-") ? "-" : "+");
                    jhBase.setJhBaseTransactionNote(item.getNote8());
                    jhBase.setJhBaseOppositionAccount(item.getNote9());
                    jhBase.setRemark("JH数据采集入库!");
                    jhSearchList.add(jhBase);
                });
                assistPdfSearchJhBaseService.insertSearchBaseList(jhSearchList);
                log.info("共{}条JH数据入库检索成功", jhSearchList.size());
            }
        } catch (Exception e) {
            log.error("解析JH数据出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * NH数据检索入库
     *
     * @param file 要解析的文件
     */
    public void extractorNhBankData(File file) {
        // File file = new File("E:\\HzdftxDocuments\\TempInfo\\inOutDetail\\gc_nh_detail.pdf");
        try {
            PDDocument document = PDDocument.load(file);
            PDFTextStripper stripper = new PDFTextStripper();
            String text = stripper.getText(document);
            document.close();
            log.info(text);

            String content = text.replaceAll("交易⽇期 交易时间 交易摘要 交易⾦额 本次余额 对⼿信息 ⽇ 志 号 交易渠道 交易附⾔\r\n", "")
                    .replaceAll("该交易明细因不可预测的⾮⼈控技术原因可能导致数据缺失，明细内容仅供参考。\r\n", "");
            String[] splitByDate = content.split("\\b\\d{4}\\d{2}\\d{2}\\b");
            List<CommonDomain> nhList = new ArrayList<>();
            for (String s : splitByDate) {
                s = s.trim(); // 去除2头空格
                if (s.length() >= 7) {
                    // 获取该行文本前7位字符串
                    String evStr = s.substring(0, 7);
                    // 判断这7位字符串是否符合时间的正则表达式, 符合则进行分割，不符合则不进行处理
                    // yymmss格式正则表达式：([0-1]?[0-9]|2[0-3])([0-5][0-9])([0-5][0-9])+ 空格
                    Pattern pattern = Pattern.compile("([0-1]?[0-9]|2[0-3])([0-5][0-9])([0-5][0-9])+\\s");
                    boolean isMatch = pattern.matcher(evStr).matches(); // 是否符合
                    if (isMatch) {
                        // 符合则根据字符串进行分割
                        s = s.replaceFirst(evStr, "");
                    }
                }
                s = s.replaceAll(" ", "###");
                Pattern p = Pattern.compile("\r\n");
                Matcher m = p.matcher(s);
                int count = 0;
                while (m.find()) {
                    count++;
                }
                if (count >= 4) {
                    s = s.replaceFirst("\r\n", "###");
                }
                s = s.replaceAll("\r\n", "");
                String[] userContents = s.split("###");
                if (userContents.length >= 4) {
                    CommonDomain nhDomain = new CommonDomain();
                    nhDomain.setNote1(userContents[0]);
                    nhDomain.setNote2(userContents[1]);
                    nhDomain.setNote3(userContents[3]);
                    nhDomain.setNote4("");
                    nhDomain.setNote5("");
                    if (userContents.length == 6) {
                        String[] strFlags = {"超级⽹银", "银⾏柜⾯", "⾃动柜员机", "电⼦商务", "掌上银⾏", "电⼦收款机", "⾃动柜员机"};
                        if (StringUtils.containsAny(userContents[4], strFlags)) {
                            nhDomain.setNote4(userContents[4]);
                            nhDomain.setNote5(userContents[5]);
                        } else {
                            if (StringUtils.containsAny(userContents[5], strFlags)) {
                                nhDomain.setNote4(userContents[5]);
                                nhDomain.setNote5("");
                            } else {
                                nhDomain.setNote4("");
                                nhDomain.setNote5(userContents[5]);
                            }
                        }
                    } else if (userContents.length == 7) {
                        nhDomain.setNote4(userContents[5]);
                        nhDomain.setNote5(userContents[6]);
                    }
                    if (StringUtils.isNotBlank(nhDomain.getNote3())) {
                        nhDomain.setNote3(nhDomain.getNote3().replaceAll("\\d+$", ""));
                    }
                    nhList.add(nhDomain);
                }
                log.info(s);
            }
            if (!nhList.isEmpty()) {
                List<AssistPdfSearchNhBase> nhSearchList = new ArrayList<>();
                nhList.forEach(item -> {
                    AssistPdfSearchNhBase nhBase = new AssistPdfSearchNhBase();
                    nhBase.setNhBaseTransactionSummary(item.getNote1());
                    nhBase.setNhBaseTransactionAmount(new BigDecimal(item.getNote2().replace("-", "").replace("+", "")));
                    nhBase.setNhBaseTransactionType(StringUtils.startsWith(item.getNote2(), "-") ? "-" : "+");
                    nhBase.setNhBaseOppositionInformation(item.getNote3());
                    nhBase.setNhBaseTransactionChannels(item.getNote4());
                    nhBase.setNhBaseTransactionNote(item.getNote5());
                    nhBase.setRemark("NH数据采集入库!");
                    nhSearchList.add(nhBase);
                });
                assistPdfSearchNhBaseService.insertSearchBaseList(nhSearchList);
                log.info("共{}条NH数据入库检索成功", nhSearchList.size());
            }
        } catch (Exception e) {
            log.error("解析NH数据出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * WX数据检索入库
     *
     * @param filePath 要解析的文件
     */
    public void extractorWxDetailData(String filePath) {
        try {
            // String filePath = "E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\lrx_wx_detail.pdf";
            //加载PDF文档
            PdfDocument pdf = new PdfDocument();
            pdf.loadFromFile(filePath);

            //抽取表格
            PdfTableExtractor extractor = new PdfTableExtractor(pdf);
            PdfTable[] tableLists;
            List<CommonDomain> list = new ArrayList<>();
            String[] strFlag = {"交易明细对应时间段", "具体交易明细", "交易单号"};
            int pageNum = pdf.getPages().getCount();
            for (int page = 0; page < pageNum; page++) {
                tableLists = extractor.extractTable(page);
                if (tableLists != null && tableLists.length > 0) {
                    for (PdfTable table : tableLists) {
                        int row = table.getRowCount();
                        int column = table.getColumnCount();
                        for (int i = 0; i < row; i++) {
                            String content = table.getText(i, 0);
                            if (StringUtils.containsAny(content, strFlag)) {
                                continue;
                            }
                            Class<CommonDomain> aClass = CommonDomain.class;
                            CommonDomain wxDomain = aClass.newInstance();
                            for (int j = 0; j < column; j++) {
                                String text = table.getText(i, j);
                                if (StringUtils.contains(text, "\n")) {
                                    text = text.replaceAll("\n", "");
                                }
                                log.info(text);
                                int f = j + 1;
                                Method method = aClass.getDeclaredMethod("setNote" + f, String.class);
                                method.setAccessible(true);
                                method.invoke(wxDomain, text);
                            }
                            list.add(wxDomain);
                        }
                    }
                }
            }
            if (list != null && list.size() > 0) {
                List<AssistPdfSearchWxBase> wxSearchList = new ArrayList<>();
                list.forEach(item -> {
                    AssistPdfSearchWxBase wxBase = new AssistPdfSearchWxBase();
                    wxBase.setWxBaseTransactionOrder(item.getNote1());
                    wxBase.setWxBaseTransactionTypeDesc(item.getNote3());
                    wxBase.setWxBaseTransactionInoutType(item.getNote4());
                    wxBase.setWxBaseTransactionWay(item.getNote5());
                    wxBase.setWxBaseTransactionAmount(new BigDecimal(item.getNote6().replace("-", "").replace("+", "")));
                    wxBase.setWxBaseTransactionType(StringUtils.equals(wxBase.getWxBaseTransactionInoutType(), "支出") ? "-" : "+");
                    wxBase.setWxBaseTransactionTradeName(item.getNote7());
                    wxBase.setWxBaseTransactionTradeOrder(item.getNote8());
                    wxBase.setRemark("WX数据采集入库");
                    wxSearchList.add(wxBase);
                });
                assistPdfSearchWxBaseService.insertSearchBaseList(wxSearchList);
                log.info("共{}条WX数据入库检索成功", wxSearchList.size());
            }
        } catch (Exception e) {
            log.error("解析WX数据出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * WX数据检索入库
     *
     * @param filePath 要解析的文件
     */
    public void extractorWxBankData(String filePath) {
        try {
            PdfDocument pdf = new PdfDocument();
            pdf.loadFromFile(filePath);
            // pdf的总页数
            int pageTotalNum = pdf.getPages().getCount();
            // 由于spire.office只可以读取前10页pdf的内容，则进行拆分pdf
            // 份数
            int copies = pageTotalNum / 10;
            // 取余
            int remainder = pageTotalNum % 10;
            if (remainder > 0) {
                // 余数大于0, 份数+1
                copies++;
            }
            // 放置以获取到的信息
            List<CommonDomain> list = new ArrayList<>();
            // 按份数抽取表格
            for (int cps = 0; cps < copies; cps++) {
                PdfDocument doc = new PdfDocument();
                // 拆分读取的起始页
                int start = cps * 10;
                // 结尾页
                int end = (start + 9) > (pageTotalNum - 1) ? (pageTotalNum - 1) : (start + 9);
                // 将读取到的数据初始化到新的PdfDocument中
                doc.insertPageRange(pdf, start, end);
                // 通过工具抽取表格
                PdfTableExtractor extractor = new PdfTableExtractor(pdf);
                PdfTable[] tableLists;
                String[] strFlag = {"交易明细对应时间段", "具体交易明细", "交易单号"};
                int pageNum = pdf.getPages().getCount();
                for (int page = 0; page < pageNum; page++) {
                    tableLists = extractor.extractTable(page);
                    if (tableLists != null && tableLists.length > 0) {
                        for (PdfTable table : tableLists) {
                            int row = table.getRowCount();
                            int column = table.getColumnCount();
                            for (int i = 0; i < row; i++) {
                                String content = table.getText(i, 0);
                                if (StringUtils.containsAny(content, strFlag)) {
                                    continue;
                                }
                                Class<CommonDomain> aClass = CommonDomain.class;
                                CommonDomain wxDomain = aClass.newInstance();
                                for (int j = 0; j < column; j++) {
                                    String text = table.getText(i, j);
                                    /*if (StringUtils.contains(text, "\n")) {
                                        text = text.replaceAll("\n", "");
                                    }*/
                                    log.info(text);
                                    int f = j + 1;
                                    Method method = aClass.getDeclaredMethod("setNote" + f, String.class);
                                    method.setAccessible(true);
                                    method.invoke(wxDomain, text);
                                }
                                list.add(wxDomain);
                            }
                        }
                    }
                }
                doc.clone();
            }
            pdf.clone();

            // 处理提取好的数据并入库
            if (!list.isEmpty()) {
                List<AssistPdfSearchWxBase> wxSearchList = new ArrayList<>();
                list.forEach(item -> {
                    AssistPdfSearchWxBase wxBase = new AssistPdfSearchWxBase();
                    wxBase.setWxBaseTransactionOrder(item.getNote1());
                    wxBase.setWxBaseTransactionTypeDesc(item.getNote3());
                    wxBase.setWxBaseTransactionInoutType(item.getNote4());
                    wxBase.setWxBaseTransactionWay(item.getNote5());
                    wxBase.setWxBaseTransactionAmount(new BigDecimal(item.getNote6().replace("-", "").replace("+", "")));
                    wxBase.setWxBaseTransactionType(StringUtils.equals(wxBase.getWxBaseTransactionInoutType(), "支出") ? "-" : "+");
                    wxBase.setWxBaseTransactionTradeName(item.getNote7());
                    wxBase.setWxBaseTransactionTradeOrder(item.getNote8());
                    wxBase.setRemark("WX数据采集入库");
                    wxSearchList.add(wxBase);
                });
                assistPdfSearchWxBaseService.insertSearchBaseList(wxSearchList);
                log.info("共{}条WX数据入库检索成功", wxSearchList.size());
            }
        } catch (Exception e) {
            log.error("解析WX数据出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * ZFB数据检索入库
     *
     * @param filePath 要解析的文件
     */
    public void extractorZfbBankData(String filePath) {
        try {
            PdfDocument pdf = new PdfDocument();
            pdf.loadFromFile(filePath);
            // pdf的总页数
            int pageTotalNum = pdf.getPages().getCount();
            // 由于spire.office只可以读取前10页pdf的内容，则进行拆分pdf
            // 份数
            int copies = pageTotalNum / 10;
            // 取余
            int remainder = pageTotalNum % 10;
            if (remainder > 0) {
                // 余数大于0, 份数+1
                copies++;
            }
            // 放置以获取到的信息
            List<CommonDomain> list = new ArrayList<>();
            // 按份数抽取表格
            for (int cps = 0; cps < copies; cps++) {
                PdfDocument doc = new PdfDocument();
                // 拆分读取的起始页
                int start = cps * 10;
                // 结尾页
                int end = (start + 9) > (pageTotalNum - 1) ? (pageTotalNum - 1) : (start + 9);
                // 将读取到的数据初始化到新的PdfDocument中
                doc.insertPageRange(pdf, start, end);
                // 通过工具抽取表格
                PdfTableExtractor extractor = new PdfTableExtractor(pdf);
                PdfTable[] tableLists;
                String[] strFlag = {"交易时间段：", "交易类型：全部", "收/支"};
                int pageNum = pdf.getPages().getCount();
                for (int page = 0; page < pageNum; page++) {
                    tableLists = extractor.extractTable(page);
                    if (tableLists != null && tableLists.length > 0) {
                        for (PdfTable table : tableLists) {
                            int row = table.getRowCount();
                            int column = table.getColumnCount();
                            for (int i = 0; i < row; i++) {
                                String content = table.getText(i, 0);
                                if (StringUtils.containsAny(content, strFlag)) {
                                    continue;
                                }
                                Class<CommonDomain> aClass = CommonDomain.class;
                                CommonDomain wxDomain = aClass.newInstance();
                                for (int j = 0; j < column; j++) {
                                    String text = table.getText(i, j);
                                    /*if (StringUtils.contains(text, "\n")) {
                                        text = text.replaceAll("\n", "");
                                    }*/
                                    log.info(text);
                                    int f = j + 1;
                                    Method method = aClass.getDeclaredMethod("setNote" + f, String.class);
                                    method.setAccessible(true);
                                    method.invoke(wxDomain, text);
                                }
                                list.add(wxDomain);
                            }
                        }
                    }
                }
                doc.clone();
            }
            pdf.clone();

            // 处理提取好的数据并入库
            if (!list.isEmpty()) {
                List<AssistPdfSearchZfbBase> zfbSearchList = new ArrayList<>();
                list.forEach(item -> {
                    AssistPdfSearchZfbBase zfbBase = new AssistPdfSearchZfbBase();
                    zfbBase.setZfbBaseTransactionInout(item.getNote1());
                    zfbBase.setZfbBaseTransactionOpposition(item.getNote2());
                    zfbBase.setZfbBaseTransactionTradeDesc(item.getNote3());
                    zfbBase.setZfbBaseTransactionWay(item.getNote4());
                    zfbBase.setZfbBaseTransactionAmount(new BigDecimal(item.getNote5().replace("-", "").replace("+", "")));
                    zfbBase.setZfbBaseTransactionType(StringUtils.equals(zfbBase.getZfbBaseTransactionInout(), "支出") ? "-" : "+");
                    zfbBase.setZfbBaseTransactionTradeAccount(item.getNote7());
                    zfbBase.setRemark("ZFB数据采集入库");
                    zfbSearchList.add(zfbBase);
                });
                assistPdfSearchZfbBaseService.insertSearchBaseList(zfbSearchList);
                log.info("共{}条ZFB数据入库检索成功", zfbSearchList.size());
            }
        } catch (Exception e) {
            log.error("解析ZFB数据出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        // extractorWxBankData("E:\\GCH\\inOutDetail\\cj_wx_detail.pdf");
        // extractorZfbBankData("E:\\GCH\\inOutDetail\\szc_zfb_detail.pdf");
    }

    /**
     * ZFB数据检索入库
     *
     * @param filePath 要解析的文件
     */
    public void extractorZfbDetailData(String filePath) {
        try {
            // String filePath = "E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\lrx_wx_detail.pdf";
            //加载PDF文档
            PdfDocument pdf = new PdfDocument();
            pdf.loadFromFile(filePath);

            //抽取表格
            PdfTableExtractor extractor = new PdfTableExtractor(pdf);
            PdfTable[] tableLists;
            List<CommonDomain> list = new ArrayList<>();
            String[] strFlag = {"交易时间段：", "交易类型：全部", "收/支"};
            int pageNum = pdf.getPages().getCount();
            for (int page = 0; page < pageNum; page++) {
                tableLists = extractor.extractTable(page);
                if (tableLists != null && tableLists.length > 0) {
                    for (PdfTable table : tableLists) {
                        int row = table.getRowCount();
                        int column = table.getColumnCount();
                        for (int i = 0; i < row; i++) {
                            String content = table.getText(i, 0);
                            if (StringUtils.containsAny(content, strFlag)) {
                                continue;
                            }
                            Class<CommonDomain> aClass = CommonDomain.class;
                            CommonDomain wxDomain = aClass.newInstance();
                            for (int j = 0; j < column; j++) {
                                String text = table.getText(i, j);
                                if (StringUtils.contains(text, "\n")) {
                                    text = text.replaceAll("\n", "");
                                }
                                log.info(text);
                                int f = j + 1;
                                Method method = aClass.getDeclaredMethod("setNote" + f, String.class);
                                method.setAccessible(true);
                                method.invoke(wxDomain, text);
                            }
                            list.add(wxDomain);
                        }
                    }
                }
            }
            if (list != null && list.size() > 0) {
                List<AssistPdfSearchZfbBase> zfbSearchList = new ArrayList<>();
                list.forEach(item -> {
                    AssistPdfSearchZfbBase zfbBase = new AssistPdfSearchZfbBase();
                    zfbBase.setZfbBaseTransactionInout(item.getNote1());
                    zfbBase.setZfbBaseTransactionOpposition(item.getNote2());
                    zfbBase.setZfbBaseTransactionTradeDesc(item.getNote3());
                    zfbBase.setZfbBaseTransactionWay(item.getNote4());
                    zfbBase.setZfbBaseTransactionAmount(new BigDecimal(item.getNote5().replace("-", "").replace("+", "")));
                    zfbBase.setZfbBaseTransactionType(StringUtils.equals(zfbBase.getZfbBaseTransactionInout(), "支出") ? "-" : "+");
                    zfbBase.setZfbBaseTransactionTradeAccount(item.getNote7());
                    zfbBase.setRemark("ZFB数据采集入库");
                    zfbSearchList.add(zfbBase);
                });
                assistPdfSearchZfbBaseService.insertSearchBaseList(zfbSearchList);
                log.info("共{}条ZFB数据入库检索成功", zfbSearchList.size());
            }
        } catch (Exception e) {
            log.error("解析WX数据出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取NH明细数据
     *
     * @param startTime     开始时间
     * @param endTime       结束时间
     * @param originalMoney 原始余额
     * @param inMoney       收总额
     * @param outMoney      支总额
     * @return 完整的数据信息
     */
    public List<NhPdfDomain> compNhDataDetail(String startTime, String endTime, Integer originalMoney, Integer inMoney, Integer outMoney) {
        BigDecimal baseMoney = new BigDecimal(originalMoney);
        Integer num = 0;
        Boolean stopIn = false;
        Boolean stopOut = false;

        // 获取数据并取出符合要求的数据 ---start
        List<NhPdfDomain> list = new ArrayList<>();
        BigDecimal inBig = new BigDecimal("0");
        BigDecimal outBig = new BigDecimal("0");
        List<AssistPdfSearchNhBase> nhList = assistPdfSearchNhBaseService.selectAssistPdfSearchNhBaseList(null);
        for (AssistPdfSearchNhBase base : nhList) {
            if (StringUtils.equals(base.getNhBaseTransactionType(), "+")) {
                if (inMoney > inBig.intValue()) {
                    // 计算当前余额
                    baseMoney = baseMoney.add(base.getNhBaseTransactionAmount());
                    BigDecimal currentMoney = baseMoney;

                    inBig = inBig.add(base.getNhBaseTransactionAmount());
                    list.add(new NhPdfDomain(base, currentMoney, num));
                    num += 1;
                } else {
                    // 已到达收所需金额，则标识可退出
                    stopIn = true;
                }
            } else if (StringUtils.equals(base.getNhBaseTransactionType(), "-")) {
                if (outMoney > outBig.intValue()) {
                    // 计算当前余额
                    baseMoney = baseMoney.subtract(base.getNhBaseTransactionAmount());
                    BigDecimal currentMoney = baseMoney;

                    outBig = outBig.add(base.getNhBaseTransactionAmount());
                    list.add(new NhPdfDomain(base, currentMoney, num));
                    num += 1;
                } else {
                    // 已到达支所需金额，则标识可退出
                    stopOut = true;
                }
            }
            if (stopIn && stopOut) {
                // 收支都已达到要求，则强制终止
                break;
            }
        }
        // 获取数据并取出符合要求的数据 ---end
        // 生成具体的日期和时间并导入到list中 ---start
        Map<String, List<String>> dateTimeMap = PDFUtil.getRandomDateTimeList(startTime, endTime, num);
        List<String> dateStrList = dateTimeMap.get("dateStrList");
        List<String> timeStrList = dateTimeMap.get("timeStrList");
        for (int i = 0; i < list.size(); i++) {
            NhPdfDomain nhBase = list.get(i);
            nhBase.setTransactionDate(dateStrList.get(i));
            nhBase.setTransactionTime(timeStrList.get(i));
        }
        // 生成具体的日期和时间并导入到list中 ---end
        return list;
    }

    /**
     * 获取JH明细数据
     *
     * @param seqNo         序号
     * @param startTime     开始时间
     * @param endTime       结束时间
     * @param originalMoney 原始余额
     * @param inMoney       收总额
     * @param outMoney      支总额
     * @return 完整的数据信息
     */
    public List<JhPdfDomain> compJhDataDetail(Integer seqNo, String startTime, String endTime, Integer originalMoney, Integer inMoney, Integer outMoney) {
        seqNo = seqNo == null ? 0 : seqNo;
        BigDecimal baseMoney = new BigDecimal(originalMoney);
        Integer num = 0;
        Boolean stopIn = false;
        Boolean stopOut = false;

        // 获取数据并取出符合要求的数据 ---start
        List<JhPdfDomain> list = new ArrayList<>();
        BigDecimal inBig = new BigDecimal("0");
        BigDecimal outBig = new BigDecimal("0");
        List<AssistPdfSearchJhBase> jhList = assistPdfSearchJhBaseService.selectAssistPdfSearchJhBaseList(null);
        for (AssistPdfSearchJhBase base : jhList) {
            if (StringUtils.equals(base.getJhBaseTransactionType(), "+")) {
                if (inMoney > inBig.intValue()) {
                    // 计算当前余额
                    baseMoney = baseMoney.add(base.getJhBaseTransactionAmount());
                    BigDecimal currentMoney = baseMoney;

                    seqNo++;
                    inBig = inBig.add(base.getJhBaseTransactionAmount());
                    list.add(new JhPdfDomain(base, seqNo, currentMoney));
                    num += 1;
                } else {
                    // 已到达收所需金额，则标识可退出
                    stopIn = true;
                }
            } else if (StringUtils.equals(base.getJhBaseTransactionType(), "-")) {
                if (outMoney > outBig.intValue()) {
                    // 计算当前余额
                    BigDecimal tempBaseMoney = baseMoney;
                    baseMoney = baseMoney.subtract(base.getJhBaseTransactionAmount());
                    BigDecimal currentMoney = baseMoney;
                    if (currentMoney.compareTo(BigDecimal.ZERO) > 0) {
                        seqNo++;
                        outBig = outBig.add(base.getJhBaseTransactionAmount());
                        list.add(new JhPdfDomain(base, seqNo, currentMoney));
                        num += 1;
                    } else {
                        baseMoney = tempBaseMoney;
                    }
                } else {
                    // 已到达支所需金额，则标识可退出
                    stopOut = true;
                }
            }
            if (stopIn && stopOut) {
                // 收支都已达到要求，则强制终止
                break;
            }
        }
        // 获取数据并取出符合要求的数据 ---end
        // 生成具体的日期和时间并导入到list中 ---start
        Map<String, List<String>> dateTimeMap = PDFUtil.getRandomDateTimeList(startTime, endTime, num);
        List<String> dateStrList = dateTimeMap.get("dateStrList");
        for (int i = 0; i < list.size(); i++) {
            JhPdfDomain nhBase = list.get(i);
            nhBase.setTransactionDate(dateStrList.get(i));
        }
        // 生成具体的日期和时间并导入到list中 ---end
        return list;
    }


    /**
     * 获取WX明细数据
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param inMoney   收总额
     * @param outMoney  支总额
     * @return 完整的数据信息
     */
    public List<WxPdfDomain> compWxDataDetail(String startTime, String endTime, Integer inMoney, Integer outMoney) {
        Integer num = 0;
        Boolean stopIn = false;
        Boolean stopOut = false;

        // 获取数据并取出符合要求的数据 ---start
        List<WxPdfDomain> list = new ArrayList<>();
        BigDecimal inBig = new BigDecimal("0");
        BigDecimal outBig = new BigDecimal("0");
        List<AssistPdfSearchWxBase> wxList = assistPdfSearchWxBaseService.selectAssistPdfSearchWxBaseList(null);
        for (AssistPdfSearchWxBase base : wxList) {
            if (StringUtils.equals(base.getWxBaseTransactionType(), "+")) {
                if (inMoney > inBig.intValue()) {
                    inBig = inBig.add(base.getWxBaseTransactionAmount());
                    list.add(new WxPdfDomain(base, num));
                    num += 1;
                } else {
                    // 已到达收所需金额，则标识可退出
                    stopIn = true;
                }
            } else if (StringUtils.equals(base.getWxBaseTransactionType(), "-")) {
                if (outMoney > outBig.intValue()) {
                    outBig = outBig.add(base.getWxBaseTransactionAmount());
                    list.add(new WxPdfDomain(base, num));
                    num += 1;
                } else {
                    // 已到达支所需金额，则标识可退出
                    stopOut = true;
                }
            }
            if (stopIn && stopOut) {
                // 收支都已达到要求，则强制终止
                break;
            }
        }
        // 获取数据并取出符合要求的数据 ---end
        // 生成具体的日期和时间并导入到list中 ---start
        Map<String, List<String>> dateTimeMap = PDFUtil.getRandomDateTimeList(startTime, endTime, num);
        List<String> dateStrList = dateTimeMap.get("dateStrList");
        List<String> timeStrList = dateTimeMap.get("timeStrList");
        for (int i = 0; i < list.size(); i++) {
            WxPdfDomain wxBase = list.get(i);
            wxBase.setTransactionDate(dateStrList.get(i));
            wxBase.setTransactionTime(timeStrList.get(i));
        }
        // 生成具体的日期和时间并导入到list中 ---end
        return list;
    }


    public static void main1(String[] args) {
        try {
            // 打开PDF文档
            PDDocument document = PDDocument.load(new File("E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\2405201013036489094(1).pdf"));

            // 创建PDFTextStripper对象，用于提取文档内容
            PDFTextStripper textStripper = new PDFTextStripper();

            // 提取文档内容
            String content = textStripper.getText(document);

            // 打印文档内容
            System.out.println(content);
            String temp = content.replace("\r\n", " ");
            System.out.println("处理后：" + temp);
            String[] split = temp.split("\\b\\d{4}\\d{2}\\d{2}\\b");
            for (String s : split) {
                System.out.println(s);
            }
            // 关闭文档
            document.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 按表格读取文件内容
    // JH可用
    public static void main3(String[] args) throws Exception {
        //加载PDF文档
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromFile("E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\jh_detail.pdf");

        //创建StringBuilder类的实例
        StringBuilder builder = new StringBuilder();

        //抽取表格
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);
        PdfTable[] tableLists;
        List<CommonDomain> list = new ArrayList<>();
        for (int page = 0; page < pdf.getPages().getCount(); page++) {
            tableLists = extractor.extractTable(page);
            if (tableLists != null && tableLists.length > 0) {
                for (PdfTable table : tableLists) {
                    List<String[]> detailList = new ArrayList<>();
                    int row = table.getRowCount();
                    int column = table.getColumnCount();
                    for (int i = 1; i < row; i++) {
                        for (int j = 0; j < column; j++) {
                            String text = table.getText(i, j);
                            if (StringUtils.contains(text, "\n")) {
                                String[] detailArray = text.split("\n");
                                detailList.add(detailArray);
                            }
                        }
                    }
                    if (detailList != null && detailList.size() > 0) {
                        int rowNum = detailList.get(0).length;
                        int size = detailList.size();
                        for (int i = 0; i < rowNum; i++) {
                            Class<CommonDomain> aClass = CommonDomain.class;
                            CommonDomain commonDomain = aClass.newInstance();
                            for (int h = 0; h < size; h++) {
                                int f = h + 1;
                                Method method = aClass.getDeclaredMethod("setNote" + f, String.class);
                                method.setAccessible(true);
                                try {
                                    String value = detailList.get(h)[i]; // 值
                                    log.info("正常给值...");
                                    method.invoke(commonDomain, value);
                                } catch (ArrayIndexOutOfBoundsException e) {
                                    log.info("数组越界，默认给空子串");
                                    method.invoke(commonDomain, "");
                                }
                            }
                            list.add(commonDomain);
                        }
                    }
                }
            }
        }
        if (list != null && list.size() > 0) {
            for (CommonDomain commonDomain : list) {
                // 插入到明细汇聚表
                AssistPdfSearchBase search = new AssistPdfSearchBase();
                search.setSearchBaseType(commonDomain.getNote2());
                search.setSearchBaseNameType("建行");
                search.setSearchBaseNameDesc(commonDomain.getNote2());
                search.setSearchBaseNameNote(commonDomain.getNote8());
                search.setSearchBaseNameAccount(commonDomain.getNote9());
                if (!StringUtils.contains(commonDomain.getNote6(), "-")) {
                    search.setSearchBaseType("0"); // 收入
                } else {
                    search.setSearchBaseType("1"); // 支出
                }
                if (StringUtils.isNotBlank(commonDomain.getNote6())) {
                    search.setSearchBaseNameMoney(new BigDecimal(commonDomain.getNote6()));
                }
                search.setRemark("数据采集入库");
                // 入库保存记录
                log.info(search.toString());
                // builder.append(jsDomain.toString() + "\n");
            }
        }
        //将提取的表格内容写入txt文档
        FileWriter fileWriter = new FileWriter("E:\\HzdftxDocuments\\TempInfo\\inOutDetail\\jhDetail.txt");
        fileWriter.write(builder.toString());
        fileWriter.flush();
        fileWriter.close();
    }

    // Wx可用（还需检验 13页后获取不到table数据）
    public static void mainWx(String[] args) throws Exception {
        //加载PDF文档
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromFile("E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\lrx_wx_detail.pdf");

        //创建StringBuilder类的实例
        StringBuilder builder = new StringBuilder();

        //抽取表格
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);
        PdfTable[] tableLists;
        List<WxDomain> list = new ArrayList<>();
        String[] strFlag = {"交易明细对应时间段", "具体交易明细", "交易单号"};
        int pageNum = pdf.getPages().getCount();
        for (int page = 0; page < pageNum; page++) {
            tableLists = extractor.extractTable(page);
            if (tableLists != null && tableLists.length > 0) {
                for (PdfTable table : tableLists) {
                    int row = table.getRowCount();
                    int column = table.getColumnCount();
                    for (int i = 0; i < row; i++) {
                        String content = table.getText(i, 0);
                        if (StringUtils.containsAny(content, strFlag)) {
                            continue;
                        }
                        Class<WxDomain> aClass = WxDomain.class;
                        WxDomain wxDomain = aClass.newInstance();
                        for (int j = 0; j < column; j++) {
                            String text = table.getText(i, j);
                            if (StringUtils.contains(text, "\n")) {
                                text = text.replaceAll("\n", "");
                            }
                            log.info(text);
                            int f = j + 1;
                            Method method = aClass.getDeclaredMethod("setNote" + f, String.class);
                            method.setAccessible(true);
                            method.invoke(wxDomain, text);
                        }
                        list.add(wxDomain);
                    }
                }
            }
        }
        if (list != null && list.size() > 0) {
            List<AssistPdfSearchBase> searchList = new ArrayList<>();
            for (WxDomain wxDomain : list) {
                // 插入到明细汇聚表
                AssistPdfSearchBase search = new AssistPdfSearchBase();
                search.setSearchBaseName(wxDomain.getNote5()); // 交易方式
                search.setSearchBaseNameType("微信"); // 所属类别
                search.setSearchBaseNameDesc(wxDomain.getNote7()); // 交易对方
                search.setSearchBaseNameNote(wxDomain.getNote3()); // 交易类型
                search.setSearchBaseNameAccount(wxDomain.getNote1() + "###" + wxDomain.getNote8()); // 交易单号 ### 商户单号
                if (!StringUtils.contains(wxDomain.getNote6(), "-")) { // 交易类型
                    search.setSearchBaseType("0"); // 收入
                } else {
                    search.setSearchBaseType("1"); // 支出
                }
                if (StringUtils.isNotBlank(wxDomain.getNote6())) { // 交易金额
                    search.setSearchBaseNameMoney(new BigDecimal(wxDomain.getNote2().replace("-", "").replace("+", "")));
                }
                search.setRemark("数据采集入库");
                searchList.add(search);
                log.info(search.toString());
            }
            // 入库保存记录
            // assistPdfSearchBaseService.insertSearchBaseList(searchList);
            log.info("保存{} 条WX检索数据成功!", searchList.size());
        }
    }

    // Wx可用（还需检验 13页后获取不到table数据）
    public static void main7(String[] args) throws Exception {
        //加载PDF文档
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromFile("E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\lrx_wx_detail.pdf");


        //创建StringBuilder类的实例
        StringBuilder builder = new StringBuilder();

        //抽取表格
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);
        PdfTable[] tableLists;
        List<WxDomain> list = new ArrayList<>();
        String[] strFlag = {"交易明细对应时间段", "具体交易明细", "交易单号"};
        int pageNum = pdf.getPages().getCount();
        for (int page = 0; page < pageNum; page++) {
            tableLists = extractor.extractTable(page);
            if (tableLists != null && tableLists.length > 0) {
                for (PdfTable table : tableLists) {
                    int row = table.getRowCount();
                    int column = table.getColumnCount();
                    for (int i = 0; i < row; i++) {
                        String content = table.getText(i, 0);
                        if (StringUtils.containsAny(content, strFlag)) {
                            continue;
                        }
                        Class<WxDomain> aClass = WxDomain.class;
                        WxDomain wxDomain = aClass.newInstance();
                        for (int j = 0; j < column; j++) {
                            String text = table.getText(i, j);
                            if (StringUtils.contains(text, "\n")) {
                                text = text.replaceAll("\n", "");
                            }
                            log.info(text);
                            int f = j + 1;
                            Method method = aClass.getDeclaredMethod("setNote" + f, String.class);
                            method.setAccessible(true);
                            method.invoke(wxDomain, text);
                        }
                        list.add(wxDomain);
                    }
                }
            }
        }
        if (list != null && list.size() > 0) {
            for (WxDomain wxDomain : list) {
                log.info(wxDomain.toString());
            }
        }
    }

    public static void main5(String[] args) {
        readPdfText("E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\gc_nh_detail.pdf");
    }

    // 按行读取PDF文件内容
    // NH测试
    public static String readPdfText(String path) {
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromFile(path);
        StringBuffer sb = new StringBuffer();
        List list = new ArrayList();
        try {
            for (int i = 0; i < pdf.getPages().getCount(); i++) {
                PdfPageBase page = pdf.getPages().get(i);
                sb.append(page.extractText(true));
                list.add(page.extractText(true).replaceAll("(.)\\1+", "$1").replaceAll(" º", "º"));
            }

            //将提取的表格内容写入txt文档
            FileWriter fileWriter = new FileWriter("E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\nhDetail.txt");
            fileWriter.write(sb.toString());
            fileWriter.flush();
            fileWriter.close();

        } catch (Exception e) {

        } finally {
            if (pdf != null) {
                pdf.close();
            }
        }
        return list.toString();
    }

    // NH整行读取后再做细分
    public static void main6(String[] args) throws Exception {
        File file = new File("E:\\GCH\\testFileColl\\assionFileTemp\\inOutDetail\\gc_nh_detail.pdf");
        PDDocument document = PDDocument.load(file);
        PDFTextStripper stripper = new PDFTextStripper();
        String text = stripper.getText(document);
        log.info(text);
        t(text);
        document.close();
    }

    private static List<List<String>> t(String text) {
        List<List<String>> tableData = new ArrayList<>();
        String content = text.replaceAll("交易⽇期 交易时间 交易摘要 交易⾦额 本次余额 对⼿信息 ⽇ 志 号 交易渠道 交易附⾔\r\n", "")
                .replaceAll("该交易明细因不可预测的⾮⼈控技术原因可能导致数据缺失，明细内容仅供参考。\r\n", "");
        String[] splitByDate = content.split("\\b\\d{4}\\d{2}\\d{2}\\b");
        List<NhDomain> nhList = new ArrayList<>();
        for (String s : splitByDate) {
            s = s.trim(); // 去除2头空格
            if (s.length() >= 7) {
                // 获取该行文本前7位字符串
                String evStr = s.substring(0, 7);
                // 判断这7位字符串是否符合时间的正则表达式, 符合则进行分割，不符合则不进行处理
                // yymmss格式正则表达式：([0-1]?[0-9]|2[0-3])([0-5][0-9])([0-5][0-9])+ 空格
                Pattern pattern = Pattern.compile("([0-1]?[0-9]|2[0-3])([0-5][0-9])([0-5][0-9])+\\s");
                boolean isMatch = pattern.matcher(evStr).matches(); // 是否符合
                if (isMatch) {
                    // 符合则根据字符串进行分割
                    s = s.replaceFirst(evStr, "");
                }
            }
            s = s.replaceAll(" ", "###");
            Pattern p = Pattern.compile("\r\n");
            Matcher m = p.matcher(s);
            int count = 0;
            while (m.find()) {
                count++;
            }
            if (count >= 4) {
                s = s.replaceFirst("\r\n", "###");
            }
            s = s.replaceAll("\r\n", "");
            String[] userContents = s.split("###");
            if (userContents != null && userContents.length >= 4) {
                NhDomain nhDomain = new NhDomain();
                nhDomain.setNote1(userContents[0]);
                nhDomain.setNote2(userContents[1]);
                nhDomain.setNote3(userContents[3]);
                nhDomain.setNote4("");
                nhDomain.setNote5("");
                if (userContents.length == 6) {
                    String[] strFlags = {"超级⽹银", "银⾏柜⾯", "⾃动柜员机", "电⼦商务", "掌上银⾏", "电⼦收款机", "⾃动柜员机"};
                    if (StringUtils.containsAny(userContents[4], strFlags)) {
                        nhDomain.setNote4(userContents[4]);
                        nhDomain.setNote5(userContents[5]);
                    } else {
                        if (StringUtils.containsAny(userContents[5], strFlags)) {
                            nhDomain.setNote4(userContents[5]);
                            nhDomain.setNote5("");
                        } else {
                            nhDomain.setNote4("");
                            nhDomain.setNote5(userContents[5]);
                        }
                    }
                } else if (userContents.length == 7) {
                    nhDomain.setNote4(userContents[5]);
                    nhDomain.setNote5(userContents[6]);
                }
                if (StringUtils.isNotBlank(nhDomain.getNote3())) {
                    nhDomain.setNote3(nhDomain.getNote3().replaceAll("\\d+$", ""));
                }
                nhList.add(nhDomain);
            }
            log.info(s);
        }
        if (nhList != null && nhList.size() > 0) {
            for (NhDomain nhDomain : nhList) {
                log.info(nhDomain.toString());
            }
        }
        return tableData;
    }

}
